package com.fastlib.adapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.android.volley.RequestQueue;
import com.android.volley.Response.ErrorListener;
import com.android.volley.VolleyError;
import com.android.volley.Request.Method;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.ImageLoader.ImageCache;
import com.android.volley.toolbox.ImageLoader.ImageContainer;
import com.android.volley.toolbox.ImageLoader.ImageListener;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.fastlib.base.OldViewHolder;
import com.fastlib.interf.AdapterViewState;
import com.library.fastlibrary.R;

import android.content.Context;
import android.graphics.Bitmap;
import android.support.annotation.NonNull;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;

/**
 * 绑定适配器，将视图与服务器中的数据捆绑，达到集合开发的目的。
 * 这个类能加快开发速度，不过可能弹性较差
 * 
 * @param <T>
 */
public abstract class BindingAdapter<T> extends BaseAdapter {
	
	private Context mContext;
	private AdapterViewState mViewState;
	private String mUri;
	private List<T> mData;
	private Map<String,Object> mRemoteParams;
	private Map<Integer,String> mBindingMap;
	private RequestQueue mQueue;
	private StringRequest mStrRequest=null;
	private int mItemLayoutId;
	private int mLoadCount;
	private boolean isMore,isLoading;
	
	private Listener<String> listener=new Listener<String>(){

		@Override
		public void onResponse(String response) {
			List<T> t=translate(response);
			isLoading=false;
			if(t==null||t.size()<mLoadCount){
				if(mViewState!=null)
					mViewState.onStateChanged(AdapterViewState.STATE_NO_MORE);
				if(t==null)
				    return;
			}
			mData.addAll(t);
			BindingAdapter.this.notifyDataSetChanged();
			if(mViewState!=null)
			    mViewState.onStateChanged(AdapterViewState.STATE_LOADED);
			mRemoteParams=getRemoteParams();
		}
	};
	
	private ErrorListener errorListener=new ErrorListener(){
		@Override
		public void onErrorResponse(VolleyError error) {
			if(mViewState!=null)
			    mViewState.onStateChanged(AdapterViewState.STATE_ERROR);
			isLoading=false;
		}
	};
	
//	public abstract Map<Integer,String> getBindingMap(T data);
	public abstract void binding(int position,T data,OldViewHolder holder);
	public abstract Map<String,Object> getRemoteParams();
	public abstract List<T> translate(String response);
	
	public BindingAdapter(Context context,String uri,@NonNull int resId){
		mContext=context;
		mUri=uri;
		mLoadCount=1;
		mData=new ArrayList<T>();
		mItemLayoutId=resId;
		isMore=true;
		isLoading=false;
		mQueue=Volley.newRequestQueue(context);
		mRemoteParams=getRemoteParams();
//		mBindingMap=getBindingMap();
		generateRequest();
//		checkBinding();
		refresh();
	}

	@Override
	public int getCount() {
		return mData==null?0:mData.size();
	}

	@Override
	public T getItem(int position) {
		return mData.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		final OldViewHolder viewHolder = getViewHolder(position, convertView, parent);
		if(position>=getCount()-1&&isMore&&!isLoading)
			loadRemoteData();
		binding(position,mData.get(position),viewHolder);
		return viewHolder.getConvertView();
	}
	
	public void setRemoteParams(Map<String,Object> params){
		mRemoteParams=params;
	}
	
	public void refresh(){
		mData.clear();
		loadRemoteData();
	}
	
	private OldViewHolder getViewHolder(int position, View convertView, ViewGroup parent) {
		return OldViewHolder.get(mContext, convertView, parent, mItemLayoutId, position);
	}
	
	/**
	 * 向服务器请求的参数
	 */
	private void loadRemoteData(){
		isLoading=true;
		if(mViewState!=null)
			mViewState.onStateChanged(AdapterViewState.STATE_LOADING);
		if(mStrRequest!=null)
			mQueue.add(mStrRequest);
	}
	
	/**
	 * 生成请求
	 */
	private void generateRequest(){
		boolean strRequest=true;
		Iterator<String> iter=mRemoteParams.keySet().iterator();
		
		while(iter.hasNext()){
			String id=iter.next();
			Object obj=mRemoteParams.get(id);
			if(!(obj instanceof String)){
				strRequest=false;
				break;
			}
		}
		
		if(strRequest){
			mStrRequest=new StringRequest(Method.POST,mUri,listener,errorListener){
				@Override
				public Map<String,String> getParams(){
					Map<String,String> map=new HashMap<String,String>();
					Set<String> keys=mRemoteParams.keySet();
					Iterator<String> iter=keys.iterator();
					
					while(iter.hasNext()){
						String key=iter.next();
						Object obj=mRemoteParams.get(key);
						if(obj instanceof String)
							map.put(key,(String)obj);
					}
					return map;
				}
			};
		}
	}
	
	public void setViewStateListener(AdapterViewState state){
		mViewState=state;
	}
	
	public void setLoadCount(int count){
		mLoadCount=count;
	}
	
	public void loadImage(ImageView iv,String uri){
		ImageLoader loader=new ImageLoader(mQueue,new ImageCache(){

			@Override
			public Bitmap getBitmap(String url) {
				return null;
			}

			@Override
			public void putBitmap(String url, Bitmap bitmap) {
				
			}
		});
		loader.get(uri,ImageLoader.getImageListener(iv, R.drawable.ic_launcher,R.drawable.error_default));
	}
}
